

%%

%byaccj

%{

  StringBuffer string = new StringBuffer();

  /* store a reference to the parser object */
  private Parser yyparser;

  /* constructor taking an additional parser object */
  public Yylex(java.io.Reader r, Parser yyparser) {
    this(r);
    this.yyparser = yyparser;
  }
  
  /* basic print statement */
  public void print(String str) {
	System.out.println("Matched: " + str);
  }
  
  /* print error; desc: description of the error, err: error msg */
  /* We can also do in this way: throw new Error(desc, err); */
  public void error(String desc, String err) {
	System.out.println(desc);
	System.out.println(err);
  }

  /* removes white space from string */
  public String strip_ws(String yytext) {
	StringTokenizer st = new StringTokenizer(yytext," ", false);
	String str = "";
	while (st.hasMoreElements())
		str += st.nextElement();
	return str;
  }
  
  /* returns token and prints */
  public int send_token (int tok) {
  	print ("Send token: "+tok);
  	return tok;
  }

%}

/* whitespace */
WS = [\n\t\r ]*

/* comments */
COM = "<!--" .*? "-->"

/* attribute name */
NAME = ([a-zA-Z]+)
IDNAME = "id" | "pageID" | "styleID" | "varID" | "textID"
VALNAME = "value"

/* expressions & operators */
OP = "+" | "-" | "/" | "*"
NUMBER = [0-9]+

/* literal values*/
LIT = (\"[^\"]*\")
NUM_LIT = {NUMBER} | (\"{NUMBER}\")

/* id values */
ID = (\$?[a-zA-Z][a-zA-Z0-9_-]*)

/* text (content between open & close tags) */
TEXT = ([^\<\>]*)

/* self-contained tags */
TAG = (\<\/?[^\>]+\/?\>)
CT = \>

/* reserved keywords */
T_NUDROID	= "<NuDroid"
T_NAVIGATION = "<navigation"
T_STYLE = "<style"
T_PAGE = "<page"
T_TEXT = "<text"
T_BUTTON = "<button"
T_LINK = "<link"
T_LIST = "<list"
T_IMAGE = "<image"
T_TABLE = "<table"
T_AUDIO = "<audio"
T_VIDEO = "<video"
T_FUNCTION = "<function"
T_VAR = "<var"
T_INPUT = "<input"
T_GETINPUT = "<getInput"
T_GOTO = "<goto"
T_SETVAR = "<setVar"
T_GETVAR = "<getVar"
T_SETTEXT = "<setText"
T_GETTEXT = "<getText"
T_TEST = "<test"
T_TRUE = "<true"
T_FALSE = "<false"
T_LOOP = "<loop"
CT_NUDROID = "</NuDroid>"
CT_NAVIGATION = "</navigation>"
CT_STYLE = "</style>"
CT_PAGE = "</page>"
CT_TEXT = "</text>"
CT_BUTTON = "</button>"
CT_LINK = "</link>"
CT_LIST = "</list>"
CT_IMAGE = "</image>"
CT_TABLE = "</table>"
CT_AUDIO = "</audio>"
CT_VIDEO = "</video>"
CT_FUNCTION = "</function>"
CT_VAR = "</var>"
CT_INPUT = "</input>"
CT_TEST = "</test>"
CT_TRUE = "</true>"
CT_FALSE = "</false>"
CT_LOOP = "</loop>"

%state TAG 
/* state that accepts any valid tag, except NuDroid */
%state ATTR			
/* state that accepts a form of attribute name */
%state ATTRVALUE	
/* state that accepts a form of value for attribute */
%state IDVALUE		
/* state that accepts only identifiers */
%state BODY		
/* state that accepts content between open and close tag */


%state EXPVALUE		
/* state that accepts expressions */

%state STYLEATTR	
/* state that accepts only style attributes */
%state STYLEATTRVALUE
/* state that accepts only style attribute values */
%state STYLE		
/* state that accepts only style body */
%state STYLEVALUE	
/* state that accepts only style body values */

%state END	
/* state that does not accept anything because the app is done */

%%

{WS}	{ /* strip out */ }

{COM}	{ /* strip out */ }

/******* looking for <NuDroid> to begin document */
<YYINITIAL> {T_NUDROID}			{	yybegin(ATTR); 
									print(yytext()); 
									send_token(Parser.T_NUDROID); }

/* if anything else, then return error */
<YYINITIAL> {TAG}				{	error("Illegal inital tag", yytext()); }

/******* looking for any valid start tag */
<TAG,BODY> {

 {T_NAVIGATION}{WS}					{	yybegin(ATTR); 
										print(yytext());
										send_token(Parser.T_NAVIGATION); }

 {T_STYLE}{WS}						{ 	yybegin(STYLEATTR); 
										print(yytext());
										send_token(Parser.T_STYLE); }
 
 {T_PAGE}{WS}						{	yybegin(ATTR); 
 										print(yytext());
										send_token(Parser.T_PAGE); }

 {T_TEXT}{WS}						{	yybegin(ATTR);									
										print(yytext());
										send_token(Parser.T_TEXT); }

 {T_BUTTON}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_BUTTON); }

 {T_LINK}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_LINK); }
 
 {T_LIST}{WS}						{	yybegin(ATTR); 								
										print(yytext());
										send_token(Parser.T_LIST); } 
 
 {T_IMAGE}{WS}						{	yybegin(ATTR);
										print(yytext());
										send_token(Parser.T_IMAGE); } 
 
 {T_TABLE}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_TABLE); } 
 
 {T_AUDIO}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_AUDIO); } 
 
 {T_VIDEO}{WS}						{	yybegin(ATTR);
										print(yytext());
										send_token(Parser.T_VIDEO); } 
 
 {T_FUNCTION}{WS}					{	yybegin(ATTR);
										print(yytext());
										send_token(Parser.T_FUNCTION); } 
 
 {T_VAR}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_VAR); } 
 
 {T_INPUT}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_INPUT); } 
 
 {T_GETINPUT}{WS}					{	yybegin(ATTR);
										print(yytext());
										send_token(Parser.T_GETINPUT); } 
 
 {T_GOTO}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_GOTO); } 
 
 {T_SETVAR}{WS}						{	yybegin(ATTR);
										print(yytext());
										send_token(Parser.T_SETVAR); } 
 
 {T_GETVAR}{WS}						{	yybegin(ATTR);
										print(yytext());
										send_token(Parser.T_GETVAR); } 
 
 {T_SETTEXT}{WS}					{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_SETTEXT); } 
 
 {T_GETTEXT}{WS}					{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_GETTEXT); } 
 
 {T_TEST}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_TEST); } 
 
 {T_TRUE}{WS}						{	yybegin(ATTR);
										print(yytext());
										send_token(Parser.T_TRUE); } 
 
 {T_FALSE}{WS}						{	yybegin(ATTR);
										print(yytext());
										send_token(Parser.T_FALSE); } 
 
 {T_LOOP}{WS}						{	yybegin(ATTR);								
										print(yytext());
										send_token(Parser.T_LOOP); } 

}

/******* looking for attribute name */
<ATTR, STYLEATTR> {

 {IDNAME}{WS}={WS}			{	//yyparser.yylval = new ParserVal(yytext());
								yybegin(IDVALUE);
								print(yytext());
								send_token(yycharat(0)); }

 {VALNAME}{WS}={WS}			{	//yyparser.yylval = new ParserVal(yytext());
								yybegin(EXPVALUE);
								print(yytext());
								send_token(yycharat(0)); }
								
 {NAME}{WS}={WS}			{	//yyparser.yylval = new ParserVal(yytext());
								if (yystate() == Yylex.STYLEATTR)
									yybegin(STYLEATTRVALUE);
								else
									yybegin(ATTRVALUE);
									
								print(yytext());
								send_token(yycharat(0)); }

 {CT}{WS}					{	//yyparser.yylval = new ParserVal(yycharat(1));
								//if (yystate() == Yylex.STYLEATTR)
								//	yybegin(STYLE);
								//else
									yybegin(BODY);
									
								print(yytext());
								send_token(yycharat(0)); }
}

/******* looking for attribute value */
<ATTRVALUE, STYLEATTRVALUE> {

 {NUM_LIT}{WS}		{	if (yystate() == Yylex.STYLEATTRVALUE)
 							yybegin(STYLEATTR);
 						else
 							yybegin(ATTR);
 							
 						print(yytext());
 						send_token(Parser.NUMBER);  }

 {LIT}{WS}			{	//if (yystate() == Yylex.STYLEATTRVALUE)
 						//	yybegin(STYLEATTR);
 						//else
 							yybegin(ATTR);
 							
 						print(yytext());
 						print(yystate());
 						send_token(Parser.STRING); }

}

<IDVALUE> \"{ID}\"{WS}	{	yybegin(ATTR);
							print(yytext());
							send_token(Parser.IDENTIFIER); }

<EXPVALUE> {

 {NUMBER}				{	print(yytext());
 							send_token(Parser.NUMBER);	}

 {OP}					{	print(yytext());
 							send_token(yycharat(0));	}

 {ID}					{	print(yytext());
 							send_token(Parser.IDENTIFIER); }

 \"						{	print(yytext()); /* ignore */ }

 \"{WS}					{	yybegin(ATTR);
 							print(yytext()); }
}


/******* looking for style body */
<STYLE> {

 {NAME}{WS}:{WS}				{	yybegin(STYLEVALUE);
									print(yytext());
									send_token(yycharat(0)); }

 {CT_STYLE}						{	yybegin(TAG);
 									print(yytext());
 									send_token(Parser.CT_STYLE); }
									
}

<STYLEVALUE> {

 {NUM_LIT}{WS};{WS}				{	yybegin(STYLE);
 									print(yytext());
 									send_token(Parser.NUMBER); }

 {LIT}{WS};{WS}					{	yybegin(STYLE);
 									print(yytext());
 									send_token(Parser.STRING); }
}

/******* looking for text or content */
<BODY> {TEXT}				{	print(yytext());
								send_token(Parser.UNFORMATTED_STRING); }

/******* looking for closing tag */
<TAG, BODY> {

 {CT_NUDROID}			{	yybegin(END);
 							print(yytext());
 							send_token(Parser.CT_NUDROID); }

 {CT_NAVIGATION}		{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_NAVIGATION); }

 {CT_PAGE}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_PAGE); }

 {CT_TEXT}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_TEXT); }
 
 {CT_BUTTON}			{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_BUTTON); }
  
 {CT_LINK}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_LINK); }
  
 {CT_LIST}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_LIST); }
  
 {CT_IMAGE}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_IMAGE); }
  
 {CT_TABLE}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_TABLE); }
  
 {CT_AUDIO} 			{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_AUDIO); }
 
 {CT_VIDEO} 			{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_VIDEO); }
 
 {CT_FUNCTION}			{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_FUNCTION); }
 							
 {CT_VAR}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_VAR); }
 
 {CT_INPUT} 			{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_INPUT); }
 
 {CT_TEST}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_TEST); }
 
 {CT_TRUE} 				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_TRUE); }
 
 {CT_FALSE} 			{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_FALSE); }
 
 {CT_LOOP}				{	yybegin(TAG);
 							print(yytext());
 							send_token(Parser.CT_LOOP); }

}

/******* looking for nothing (end of nudroid) */
<END> .					{ print("Wrong!"); }

